package p2.code;

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 缓冲池类的定义
 * 这个类安全了定义了缓冲池的读写功能
 */
public class Buffer {

    private static final int CAPACITY = 1;//缓冲区大小为1

    private LinkedList<Integer> queue = new LinkedList<>();

    //创建锁
    private static Lock lock = new ReentrantLock();

    //创建条件对象
    /**
     * Condition定义了等待/通知两种类型的方法，当前线程调用这些方法时，需要提前获取到Condition对象关联的锁。
     * Condition对象是由Lock对象（调用Lock对象的newCondition()方法）创建出来的，换句话说，Condition是依赖Lock对象的。
     */
    private static Condition notEmpty = lock.newCondition();
    private static Condition notFull = lock.newCondition();

    public void write(int value) {
        lock.lock();//上锁
        try{
            while(queue.size() == CAPACITY) {
                System.out.println("等待队列有空余位置....");
                // 释放锁，进入等待状态
                notFull.await();
            }
            //添加value到queue
            queue.offer(value);
            //通知等待的read方法
            // 可以获取锁进行下面的操作
            notEmpty.signal();
        } catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        finally{
            lock.unlock();//解锁
        }

    }

    public int read() {
        int value=0;
        lock.lock();//上锁
        try{
            while(queue.isEmpty()) {
                System.out.println("等待队列存入元素.....");
                //令read释放锁并进入等待
                notEmpty.await();
            }
            value = queue.remove();//弹出元素
            // 唤醒等待的write获取锁
            // 并进行下一步操作
            notFull.signal();
        }catch(InterruptedException ex) {
            ex.printStackTrace();
        } finally {
            //解锁
            lock.unlock();
            return value;
        }
    }

}
